package com.ruoyi.gateway.service.impl;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.annotation.Resource;
import javax.imageio.ImageIO;

import com.wf.captcha.*;
import com.wf.captcha.base.Captcha;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.FastByteArrayOutputStream;
import com.google.code.kaptcha.Producer;
import com.ruoyi.common.core.constant.CacheConstants;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.exception.CaptchaException;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.sign.Base64;
import com.ruoyi.common.core.utils.uuid.IdUtils;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.gateway.config.properties.CaptchaProperties;
import com.ruoyi.gateway.service.ValidateCodeService;

/**
 * 验证码实现处理
 *
 * @author ruoyi
 */
@Service
public class ValidateCodeServiceImpl implements ValidateCodeService
{
    @Resource(name = "captchaProducer")
    private Producer captchaProducer;

    @Resource(name = "captchaProducerMath")
    private Producer captchaProducerMath;

    @Autowired
    private RedisService redisService;

    @Autowired
    private CaptchaProperties captchaProperties;

    /**
     * 生成验证码
     */
    @Override
    public AjaxResult createCaptcha() throws IOException, CaptchaException
    {
        Captcha captcha;
        Map<String, Object> rspMap = new HashMap<>();
        boolean captchaEnabled = captchaProperties.getEnabled();
        rspMap.put("captchaEnabled", captchaEnabled);
        AjaxResult ajax = AjaxResult.success(rspMap);
        if (!captchaEnabled)
        {
            return ajax;
        }

        // 保存验证码信息
        String uuid = IdUtils.simpleUUID();
        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;

        // 验证码配置
        String captchaType = captchaProperties.getType();
        int captchaWidth = captchaProperties.getWidth();
        int captchaHeight = captchaProperties.getHeight();
        int charLength = captchaProperties.getCharLength();
        // 生成验证码
        if ("math".equals(captchaType))
        {
            // 算术类型
            captcha = new ArithmeticCaptcha(captchaWidth, captchaHeight,charLength);
            // 几位数运算，默认是两位
            // captcha.setLen(charLength);
            // 获取运算的公式：3+2=?
            // captcha.getArithmeticString();
            // 获取运算的结果：5
            // 如果不想要base64的头部data:image/png;base64, 加一个空的参数即可
        }
       else if ("gif".equals(captchaType))
        {
            // gif类型
            captcha = new GifCaptcha(captchaWidth, captchaHeight,charLength);
        }else if ("chinese".equals(captchaType))
        {
            // 中文类型
            captcha = new ChineseCaptcha(captchaWidth, captchaHeight,charLength);

        }else if ("chinesegif".equals(captchaType))
        {
            // 中文gif类型
            captcha = new ChineseGifCaptcha(captchaWidth, captchaHeight,charLength);
        } else
        {
            // png类型
            captcha = new SpecCaptcha(captchaWidth, captchaHeight,charLength);
        }

       //验证码信息存储
        redisService.setCacheObject(verifyKey, captcha.text(), Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
        rspMap.put("type", captchaType);
        rspMap.put("uuid", uuid);
        rspMap.put("img", captcha.toBase64(""));
        return ajax;
    }

    /**
     * 校验验证码
     */
    @Override
    public void checkCaptcha(String code, String uuid) throws CaptchaException
    {
        if (StringUtils.isEmpty(code))
        {
            throw new CaptchaException("验证码不能为空");
        }
        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
        String captcha = redisService.getCacheObject(verifyKey);
        if (captcha == null)
        {
            throw new CaptchaException("验证码已失效");
        }
        redisService.deleteObject(verifyKey);
        if (!code.equalsIgnoreCase(captcha))
        {
            throw new CaptchaException("验证码错误");
        }
    }
}
